package orm

import (
	"errors"
	"fmt"
	"reflect"
	"regexp"
	"strings"
	"sync"
	"time"
)

// 适配器
type Adaptor interface {
	// 获取表名
	Table(name string) string
	// 获取列名
	Column(name string) string
	// 获取参数
	Param(i int) string
}

var (
	ErrBadType = errors.New("bad type")
)

var (
	regexpUpper = regexp.MustCompile(`[A-Z]`)
)

var (
	idMutex        = new(sync.Mutex)
	idBase         = time.Now().UnixNano()
	idOffset int64 = 0
)

// 转化为下划线风格的命名
func underscore(name string) string {
	s := regexpUpper.ReplaceAllStringFunc(name, func(x string) string {
		return fmt.Sprintf("_%v", strings.ToLower(x))
	})

	if s[0] == '_' {
		return fmt.Sprintf("%v", s[1:])
	} else {
		return fmt.Sprintf("%v", s)
	}
}

// 生成ID
func genId() int64 {
	idMutex.Lock()
	defer idMutex.Unlock()

	if idOffset < 1000000 {
		idOffset += 1
	} else {
		idBase = time.Now().UnixNano()
		idOffset = 0
	}
	return idBase + idOffset
}

// 获得元素类型
func elemType(x interface{}) reflect.Type {
	t := reflect.TypeOf(x).Elem()
	if t.Kind() == reflect.Slice {
		return t.Elem().Elem()
	} else {
		return t
	}
}

// 判断是否为指针
func isPrt(t reflect.Type) bool {
	return t.Kind() == reflect.Ptr
}

// 判断是否为Slice
func isSlice(t reflect.Type) bool {
	return t.Kind() == reflect.Slice
}

// 判断是否为结构体
func isStruct(t reflect.Type) bool {
	return t.Kind() == reflect.Struct
}

// 判断是否为原子类型
func isAtom(t reflect.Type) bool {
	k := t.Kind()
	return k == reflect.String || k == reflect.Int || k == reflect.Int64 || k == reflect.Float64 || k == reflect.Bool || k == reflect.Float32 || k == reflect.Int32 || k == reflect.Int16 || k == reflect.Int8
}
